package com.ncell.utils;

import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Random;

public class Utils {

    private static final Random rand = new Random(65);

    public static int getRandomInt(double max) {
        return (int) (rand.nextDouble() * max);
    }

    public static double getRandom(double max) {
        return rand.nextDouble() * max;
    }

    public static float getRandomFloat(float max) {
        return rand.nextFloat() * max;
    }

    public static double getRandom(double min, double max) {
        return min + rand.nextDouble() * (max - min);
    }

    public static float getRandom(float min, float max) {
        return min + rand.nextFloat() * (max - min);
    }

    public static float length(float x, float y, float x2, float y2) {
        float tx = x - x2;
        float ty = y - y2;
        return (float) Math.sqrt(tx * tx + ty * ty);
    }

    /**
     * Create an Iterator from multiple Iterators. The returned Iterator
     * traverses all elements from all sources, in the order, as if they belong
     * to the same source.
     *
     * @param <T> type of elements
     * @param sources sources of the elements, in order of traversal
     * @return an iterator over multiple iterators in sequence
     */
    public static Iterator concatenate(final Iterator... sources) {
        if (sources.length == 0) {
            return new Iterator() {
                @Override
                public boolean hasNext() {
                    return false;
                }

                @Override
                public Object next() {
                    throw new NoSuchElementException("end of iteration");
                }

                @Override
                public void remove() {
                    throw new IllegalStateException("no previous element");
                }
            };
        }
        return new Iterator() {

            Iterator<Iterator> sourcesIterator = Arrays.asList(sources).iterator();
            Iterator currentIterator = sourcesIterator.next();

            @Override
            public boolean hasNext() {
                if (currentIterator.hasNext()) {
                    return true;
                } else {
                    if (sourcesIterator.hasNext()) {
                        currentIterator = sourcesIterator.next();
                        return hasNext();
                    } else {
                        return false;
                    }
                }
            }

            @Override
            public Object next() {
                if (hasNext()) {
                    return currentIterator.next();
                } else {
                    throw new NoSuchElementException("end of iteration");
                }
            }

            @Override
            public void remove() {
                currentIterator.remove();
            }
        };
    }

    /**
     * Create an Iterable from multiple Iterables. The returned Iterable
     * traverses all elements from all sources, in the order, as if they belong
     * to the same source.
     *
     * @param <T> type of elements
     * @param sources sources of the elements, in order of traversal
     * @return an iterable over multiple iterators in sequence
     */
    @SuppressWarnings("unchecked") // impossible to create a generic array
    public static <T> Iterable<T> concatenate(final Iterable<T>... sources) {
        return new Iterable() {
            @Override
            public Iterator iterator() {
                final Iterator[] iteratorsArrays = new Iterator[sources.length];
                for (int i = 0; i < sources.length; i++) {
                    iteratorsArrays[i] = sources[i].iterator();
                }
                return concatenate(iteratorsArrays);
            }
        };
    }
}
